Modal   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 69
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 55
dl 0
loc 69
rs 10
c 0
b 0
f 0
wmc 13

5 Functions

Rating   Name   Duplication   Size   Complexity  
A close 0 8 3
A confirm 0 4 2
A componentWillReceiveProps 0 4 2
B render 0 36 5
A message 0 3 1
1
import React from 'react';
2
import PropTypes from 'prop-types';
3
import {
4
  Button,
5
  Modal as RBModal,
6
  Alert,
7
} from 'react-bootstrap';
8
9
const MODE_PRESET = {
10
  default: {
11
    buttons: [
12
      { label: '닫기', onClick: (e, modal) => modal.close(false) },
13
    ],
14
    size: 'large',
15
  },
16
  alert: {
17
    buttons: [
18
      { label: '확인', onClick: (e, modal) => modal.close(false) },
19
    ],
20
    size: 'small',
21
  },
22
  confirm: {
23
    buttons: [
24
      { label: '확인', onClick: (e, modal) => modal.confirm() },
25
      { label: '취소', onClick: (e, modal) => modal.close(true) },
26
    ],
27
    size: 'small',
28
  },
29
};
30
31
export default class Modal extends React.Component {
32
  constructor(props) {
33
    super(props);
34
    this.state = {
35
      alertMessage: null,
36
    };
37
  }
38
39
  componentWillReceiveProps(newProps) {
40
    if (newProps.visible !== this.props.visible && newProps.visible) {
41
      this.setState({ alertMessage: null });
42
    }
43
  }
44
45
  close(isCancel) {
46
    if (isCancel) {
47
      if (this.props.onCancel) {
48
        this.props.onCancel();
49
      }
50
    }
51
    this.props.onClose();
52
  }
53
54
  confirm() {
55
    if (this.props.onConfirm) {
56
      this.props.onConfirm();
57
    }
58
  }
59
60
  message(message, level) {
61
    this.setState({ alertMessage: message, alertLevel: level });
62
  }
63
64
  render() {
65
    const modal = this;
66
67
    let buttons = this.props.buttons;
68
    let size = this.props.size;
69
    if (!buttons) {
70
      buttons = MODE_PRESET[this.props.mode].buttons;
71
    }
72
    if (!size) {
73
      size = MODE_PRESET[this.props.mode].size;
74
    }
75
76
    return (
77
      <RBModal show={this.props.visible} onHide={() => this.close(true)} bsSize={size} backdrop="static">
78
        <RBModal.Header closeButton>
79
          <RBModal.Title>{this.props.title}</RBModal.Title>
80
        </RBModal.Header>
81
        <RBModal.Body>
82
          <Alert style={{ display: this.props.message ? 'block' : 'none' }} bsStyle={this.props.messageLevel}>
83
            {this.props.message}
84
          </Alert>
85
          {this.props.children}
86
        </RBModal.Body>
87
        <RBModal.Footer>
88
          {buttons instanceof Array && buttons.map(button => (
89
            <Button
90
              onClick={e => (button.isClose ? this.close(true) : button.onClick(e, modal))}
91
              bsStyle={button.style || 'default'}
92
              disabled={button.disabled}
93
            >
94
              {button.label}
95
            </Button>
96
          ))}
97
        </RBModal.Footer>
98
      </RBModal>
99
    );
100
  }
101
}
102
103
Modal.defaultProps = {
104
  mode: 'default',
105
  size: MODE_PRESET.default.size,
106
  onConfirm: () => {},
107
  onCancel: () => {},
108
  buttons: null,
109
  message: '',
110
  messageLevel: 'warning',
111
};
112
113
Modal.propTypes = {
114
  visible: PropTypes.bool.isRequired,
115
  title: PropTypes.string.isRequired,
116
  size: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
117
  mode: PropTypes.oneOf(['default', 'alert', 'confirm']),
118
  onConfirm: PropTypes.func,
119
  onCancel: PropTypes.func,
120
  onClose: PropTypes.func.isRequired,
121
  buttons: PropTypes.arrayOf(PropTypes.shape({
122
    label: PropTypes.string.isRequired,
123
    onClick: PropTypes.func,
124
    style: PropTypes.oneOf(['default', 'primary', 'success', 'info', 'warning', 'danger', 'link']),
125
  })),
126
  message: PropTypes.string,
127
  messageLevel: PropTypes.string,
128
};
129